\documentclass[a4paper]{article}
\usepackage[english]{babel}
%\usepackage[utf8x]{inputenc}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{listings}
\usepackage{color}
\usepackage[margin=1in]{geometry}
\usepackage[T1]{fontenc}
\title{FRC Programming Tasks List v1.0.4}
\author{Noah Sutton-Smolin\\Yousuf Soliman\\Kian Sheik}

\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{mauve}{rgb}{0.58,0,0.82}

\lstset{frame=tb,
  language=Java,
  aboveskip=3mm,
  belowskip=3mm,
  showstringspaces=false,
%  columns=flexible,
  basicstyle={\small\ttfamily},
  numbers=none,
  numberstyle=\tiny\color{gray},
  keywordstyle=\color{blue},
  commentstyle=\color{dkgreen},
  stringstyle=\color{mauve},
  breaklines=true,
  breakatwhitespace=true
  tabsize=2
}

\begin{document}
\setcounter{tocdepth}{2}\maketitle\tableofcontents\pagebreak

This is a compilation of the introductory tasks for FRC (FIRST Robotics Competition) programming. Each of these tasks are to be completed in order. This introduction is designed to be as concise as possible, so \textbf{be sure to ask questions}. \textbf{This document is out of sync with the main repository, but almost everything is still parallel between them.}

The project folders are located in the \lstinline{intro} directory of the Subversion project. Each of the major headings in this document correspond to one of the projects in that folder; be sure you're using the right one when you advance to the next major heading!

\subsection{Initial lesson}
Don't be lazy.\\Do things right the first time.\\This is the imperative of the programmer.\\Don't be lazy.

\pagebreak\section{Basic Usage}
\subsection{\lstinline{DebugLog} usage}
\subsubsection{Goal} Learn the use of \lstinline{DebugLog} to write outputs to the console.
\subsubsection{Details} One should never use \lstinline{System.out.print*} to print console outputs. The reasons are varied, but we do this primarily because the outputs become cluttered, unreadable, and generally unusable. 

\lstinline{DebugLog} is a class designed to beautify outputs and make them readable. It does this by enforcing three things:
\begin{enumerate}\item{Log message severity, which can be filtered, as we do not always want to see the output.}\item{Log message timestamps, which do not normally come with system outs.}\item{Log message sources, which show where a message actually came from. This is critically important when diagnosing software issues.}\end{enumerate}

The severity levels in order are:

\begin{enumerate}\item{\lstinline{DebugLog.LVL_ERROR}: This is used when the program has encountered an error which will cause it to exit.}\item{\lstinline{DebugLog.LVL_SEVERE}: This is used when a part of the program cannot continue as requested.}\item{\lstinline{DebugLog.LVL_WARN}: This is used when a part of the program may not function as intended, or something has the possibilty to fail.}\item{\lstinline{DebugLog.LVL_INFO}: This is used for important operating information \textit{only}.}\item{\lstinline{DebugLog.LVL_DEBUG}: This is used for debugging outputs which are temporary and/or infrequent.}\item{\lstinline{DebugLog.LVL_STREAM}: This is used for constant outputs. For instance, controller positions are under the stream level. The difference between \lstinline{STREAM} and \lstinline{DEBUG} is critical; don't mix them up.}\end{enumerate}

The \lstinline{RobotStartup} class is actually what's run by the FRC API, and it interfaces with the \lstinline{Global} class. \textbf{You should never modify the \lstinline{RobotStartup} class.}

\subsubsection{Task} Write one output of each severity level to the console when teleop starts, in order, using the \lstinline{DebugLog} class.
\subsubsection{Success} \begin{enumerate}\item{Each output is written to the console successfully.}\item{No file has been modified except for the \lstinline{Global} class.}\item{Only the \lstinline{initializeTeleop()} method in the \lstinline{Global} class has been modified.}\item{No \lstinline{System.out.*} classes are used.}\end{enumerate}

\pagebreak\subsection{Utilizing the \lstinline{Global} class}
\subsubsection{Goal} Understand the function of the \lstinline{Global} class with respect to shared resources and robot intialization.
\subsubsection{Details} The \lstinline{Global} class is used to hold all global resources and contain initialization methods. These methods are wrapped by \lstinline{RobotStartup}, which you are free to inspect, \textbf{but not modify}.

The \lstinline{static} modifier must be used before all \lstinline{Global} variables; if you do not know what the static modifier does, you are free to do research into it. However, in short, the static modifier makes it so that only one instance of a variable can exist in a class. This means any class resource can be accessed using \lstinline{[CLASSNAME].[RESOURCENAME]} instead of \lstinline{[INSTANCENAME].[RESOURCENAME]}.

With respect to our given setup, if we had a \lstinline{Jaguar} (motor) in \lstinline{Global} declared as: \lstinline{public} \textit{\lstinline{static}} \lstinline{final Jaguar jag1 = new Jaguar(1,2);} it can be accessed from anywhere in the code by using \lstinline{Global.jag1}; however, if we declared it like so: \lstinline{public final Jaguar jag1 = new Jaguar(1,2);} without the \lstinline{static} modifier, then it could \textit{not} be accessed using \lstinline{Global.jag1}, which makes it an ineffective declaration for our purposes. We will not explain the \lstinline{static} modifier here; this is something you may look up.

The \lstinline{Watchdog} class is not something you should ever personally need to deal with, as it is handled by the system, but it is important to understand. The \lstinline{Watchdog} makes sure that the robot's code hasn't stopped or frozen. The act of ``feeding'' the watchdog ensures that the FRC system does not automatically kill our robot. The \lstinline{Watchdog} is called using: \lstinline{Watchdog.getInstance().feed();}

This gets the current instance of the Watchdog from the \lstinline{Watchdog} class (through the static \lstinline{getInstance()} method), and feeds it.
\subsubsection{Task} Create a \lstinline{Jaguar} in the \lstinline{Global} class. Change its power in each of the \lstinline{initialize*} methods. Be sure to feed the \lstinline{Watchdog} somewhere once.
\subsubsection{Success} \begin{enumerate}\item{The power was successfully set in each initialization function.}\item{\lstinline{Watchdog} was fed once.}\item{No file was modified except for \lstinline{Global}.}\end{enumerate}

\pagebreak\subsection{Understanding method timings}
\subsubsection{Goal} Understand when the initialization methods are called in-game.
\subsubsection{Details} The \lstinline{RobotStartup} class controls the timings in the \lstinline{Global} class. You need to understand when and under which circumstances the methods in the \lstinline{Global} class would be invoked. \begin{itemize}\item{\lstinline{initializeRobot()} is invoked once when the robot's code starts up.}\item{\lstinline{initializeDisabled()} is invoked once when the robot enters the disabled state before and after the game.}\item{\lstinline{initializeAutonomous()} is invoked once when the robot's autonomous phase is about to begin.}\item{\lstinline{initializeTeleop()} is invoked once when the robot's teleoperated phase is about to begin.}\end{itemize}

Every robot task in-game will be handled by the \lstinline{EventManager}. The initialization methods are only used to set up \lstinline{EventManager}'s sequencing so that everything else follows suit and makes sense. \begin{itemize}\item{\lstinline{robotKill()} is a predefined function which you can invoke when you wish to shut off the robot entirely. After invoking this method, the robot will need to be power cycled.}\item{\lstinline{robotStop()} allows you to turn off the robot without disconnecting or disabling it.}\end{itemize}
\setcounter{subsubsection}{3}\subsubsection{Success} You read this section, didn't you? Good, now go read it again.


\pagebreak\section{Sensor and Motor Usage}\setcounter{subsection}{3}

\subsection{Using raw motors with \lstinline{MotorLink}}
\subsubsection{Goal} Learn how to use the \lstinline{MotorLink} class to more efficiently interface with the \lstinline{Jaguar}s.
\subsubsection{Details} The \lstinline{MotorLink} class was written with a primary purpose of simplifying the logic beind encoders (which measure the angle of wheels) and speed controllers (which control the rate that motors move). As such, \textit{all motors should be written using} \lstinline{MotorLink}. 

It is important to understand how to declare a \lstinline{Jaguar}, though, for this task. A \lstinline{Jaguar} is a hardware link that's part of the FRC API which connects to a motor controller on the physical robot. One can control a motor through the \lstinline{Jaguar} class.

The motor you will be creating will take one argument: a \lstinline{Jaguar}. You can declare the \lstinline{Jaguar} in-line. Explore the \lstinline{MotorLink} class and its methods. Bear in mind that it has been stripped down from its full form, as \lstinline{Events} have not been introduced yet, and the \lstinline{MotorSpeedControl} (a class which controls the speed of a motor) requires events.

Motors can be given powers from $[-1.0,1.0]$; anything out of range is invalid.
\subsubsection{Task} Declare a \lstinline{MotorLink} as a static resource in \lstinline{Global}. Set its power scalar to a valid value. Set the motor power.
\subsubsection{Success} \begin{enumerate}\item{The \lstinline{MotorLink} is declared as a static resource.}\item{The \lstinline{Jaguar} is \textit{not} declared as a static resource, and is instead consumed by \lstinline{MotorLink}.}\item{The power scalar and powers are set properly.}\end{enumerate}

\pagebreak\subsection{Using and declaring sensors}
\subsubsection{Goal} Declare sensors and use their values.
\subsubsection{Details} Sensors are primarily accessible through the \lstinline{frc3128.HardwareLink} package. For instance, a gyroscope will use the \lstinline{GyroLink} class (located in \lstinline{frc3128.HardwareLink.GyroLink}) for communications. 

\lstinline{GyroLink} consumes a \lstinline{Gyroscope} (FRC API class) in its constructor.
\subsubsection{Task} Declare a new \lstinline{GyroLink} as a static \lstinline{Global} resource. Print its value in \lstinline{Global.initializeTeleop()}.
\subsubsection{Success}\begin{itemize}\item{The \lstinline{GyroLink} is declared properly.}\item{The \lstinline{Gyroscope} is consumed by the \lstinline{GyroLink} constructor.}\item{The value of the gyro is printed out when the robot initializes.}\end{itemize}

\pagebreak\subsection{Using raw encoders and angles}
\subsubsection{Goal} Create an encoder and read out its angle.
\setcounter{subsubsection}{2}\subsubsection{Task} Encoders are devices which keep track of the angle of a given motor. The \lstinline{MotorLink} class can be linked with an \lstinline{AbstractEncoder}; this is explained in more detail in task 7.

Create a \lstinline{MagneticPotEncoder} and print out its raw angle on \lstinline{Global.initializeTeleop()}.
\subsubsection{Success} \begin{itemize}\item{Only the \lstinline{MagneticPotEncoder} is kept as a static resource.}\item{The raw angle is printed out using \lstinline{DebugLog} at the appropriate level.}\end{itemize}

\pagebreak\subsection{Using motors in conjunction with encoders}
\subsubsection{Goal} Properly use raw encoders and their angles.
\subsubsection{Details} \lstinline{AbstractEncoder} is an abstract class which has two required methods: \lstinline{getAngle()} and \lstinline{getRawValue()}. There are two predefined implementations: \lstinline{GyroEncoder} and \lstinline{MagneticPotEncoder}. 

There is a static method in \lstinline{frc3128.Util.RobotMath} called \lstinline{normalizeAngle()}; this method must be invoked on all angle values continuously, as it keeps the angle values to within normal range. We keep track of angles from 0 to 360 degrees. 
\subsubsection{Task} Create a new \lstinline{MotorLink} using a \lstinline{MagneticPotEncoder}. Print out the angle, and print the normalized value to the print stream using \lstinline{DebugLog}.
\subsubsection{Success}\begin{itemize}\item{Create a \lstinline{MotorLink} and associated \lstinline{AbstractEncoder} and \lstinline{Jaguar}.}\item{The \lstinline{AbstractEncoder} and \lstinline{Jaguar} are fully consumed by the \lstinline{MotorLink}.}\item{The angle from the \lstinline{MotorLink} is normalized and printed out.}\item{The print out uses \lstinline{DebugLog}.}\end{itemize}

\pagebreak\subsection{Using \lstinline{PneumaticsManager}}
\subsubsection{Goal} Learn the uses of \lstinline{PneumaticsManager}.
\subsubsection{Details} \lstinline{PneumaticsManager} is a class designed to control the pneumatic air compression systems on the robot. The pneumatics system uses one compressor and unlimited two-sided solenoids called Festos to control air flow. 

The \lstinline{PneumaticsManager} must be passed a compressor. When a new piston is created, it returns a \lstinline{PistonID}, which is a reference value used by the \lstinline{PneumaticsManager} to handle piston movements.
\subsubsection{Task} Initialize the \lstinline{PneumaticsManager}; the \lstinline{Compressor} should be consumed. Turn the compressor off, then on. Create a piston, and record the \lstinline{PistonID} as a static global resource. Turn the piston forward, then flip its state, then reverse its polarity.


\pagebreak\section{Event Manager}\setcounter{subsection}{8}

\subsection{Single run events}
\subsubsection{Goal} Learn how and when certain events are executed, and how to trigger single-run events.
\subsubsection{Details} The \lstinline{EventManager} is a rather simple block of code which drives the entire robot. It takes \lstinline{Events}, or small blocks of code, and runs them in the sequence they were queued. The \lstinline{EventManager} is called automatically in \lstinline{RobotStartup}. Do not modfiy \lstinline{RobotStartup}. Do not manually invoke the \lstinline{EventManager} de-queueing method.

An \lstinline{Event} is an abstract class. If you don't know what abstract classes are, it is strongly suggested that you look up the documentation for them. All \lstinline{Event}s must extend the \lstinline{Event} class with: \lstinline{extends Event}. That means, to create an event, you must do the following:

\begin{lstlisting}
	class EventImpl extends Event {
		public void execute() {
			//your code
		}
	};
\end{lstlisting}

If you do not have the \lstinline{execute()} method, you will not be adhering to the \lstinline{Event} abstract class, and NetBeans will barf errors in your face. You can also declare an \lstinline{Event} inline, but it \textit{must} have an implementation.

\begin{lstlisting}
	Event e = new Event() {
		public void execute() {
			//your code
		}
	};
\end{lstlisting}

You can also declare an \lstinline{Event} inline, and directly queue it:

\begin{lstlisting}
	(new Event() {
		public void execute() {
			//your code
		}
	}).registerIterableEvent();
\end{lstlisting}

The \lstinline{Event} has several critical methods:
\begin{itemize}\item{\lstinline{Event.registerSingleEvent()} will insert the \lstinline{Event} into the \lstinline{EventManager}'s queue, where it will be run once before being removed.}\item{\lstinline{Event.registerIterableEvent()} will insert the \lstinline{Event} into the \lstinline{Event.EventManager}'s queue, and it won't be removed until it is cancelled directly (or the entire \lstinline{Event} stack is dropped through \lstinline{EventManager.dropAllEvents()}).}\item{\lstinline{Event.registerTimedEvent(int msec)} will create a new instance of a \lstinline{TimerEvent} and register it as an iterable event. When the timer expires, the selected \lstinline{Event} will be run. If you're going to invoke this method, it is \textit{highly} recommended that you call \lstinline{Event.prepareTimer()} first.}\end{itemize}

That's it for starting \lstinline{Event}s. For cancelling \lstinline{Event}s: \begin{itemize}\item{\lstinline{Event.cancelEvent()} will cancel \lstinline{Event}.}\item{\lstinline{Event.cancelTimedEvent()} will cancel \lstinline{Event}'s execution timer.}\item{\lstinline{Event.cancelEventAfter(int msec)} will cancel \lstinline{Event} after a given amount of time.}\end{itemize}

\subsubsection{Task} Create a single run event which will print out some text.

\pagebreak\subsection{Single run events and their execution order}
\subsubsection{Goal} Understand the queue nature of the \lstinline{EventManager}.
\subsubsection{Details} The \lstinline{EventManager} uses a FIFO (First In, First Out) queue. \lstinline{Events} will be run in the order they are inserted in the queue. This means that, if I add an event \lstinline{E_A} and then add an event \lstinline{E_B}, \lstinline{E_A} will run first, then \lstinline{E_B}.
\subsubsection{Task} Create a program which will print out \lstinline{"Hello"} then \lstinline{"World"}, then set a motor on \lstinline{(1,2)} to 50\% power.
\subsubsection{Success} \begin{enumerate}\item{No extraneous resources are kept.}\item{\lstinline{DebugLog} is used for printing.}\item{The motor is created using \lstinline{MotorLink} and is created as a global static resource.}\end{enumerate}

\pagebreak\subsection{Iterable Events}
\subsubsection{Goal} Understand and use iterable events.
\subsubsection{Details} Iterable events are the same as single run events, but they are not deleted on the \lstinline{EventManager}'s cleanup step. This means they will run continuously unless cancelled explicitly. Events can be registered as iterable using \lstinline{Event.registerIterableEvent()}. 

Event timers are events which are triggered after a certain amount of time. To create an event timer, use \lstinline{Event.registerTimerEvent(int msec)}.
\subsubsection{Task} Create a program which will print out \lstinline{"Hello"} continuously. After 1.5 seconds, a separate event should print out \lstinline{"World"}. 

\pagebreak\subsection{Iterable events and cancellation}
\subsubsection{Goal} Understand and use iterable events.
\subsubsection{Details} Iterable events must be cancelled manually, otherwise they will continue indefinitely.
\subsubsection{Task} Create a program which will print out \lstinline{"Hello"} continuously. After 1.5 seconds, a separate event should print out \lstinline{"World"}, at which point, the \lstinline{"Hello"} event should stop printing. 
\subsubsection{Success} \begin{enumerate}\item{No resources are kept which are not needed.}\item{It operates as described above.}\item{After two seconds, the robot should still be able to support additional code.}\end{enumerate}

\pagebreak\subsection{Events and call stack order}
\subsubsection{Goal} Experiment with events and callback orders.
\setcounter{subsubsection}{2}\subsubsection{Task} Create a program which will start by setting a motor on \lstinline{(1,2)}{} to 50\% power, then print out "Hello" continuously. Another event should stop the "Hello" event, then print out "World" and set the motor to 0\% power.

\subsection{More using events to control robots (Optional)}
\subsubsection{Goal} Understand how events are used to control the robot.
\setcounter{subsubsection}{2}\subsubsection{Task} Create a \lstinline{MotorLink} global static resource with a motor on \lstinline{(1,2)}. After 500 msec, set its power to 50\%. After 1000 msec, set its power to -50\%. After 1500 msec, set its power to 0\%. 

\subsection{More using events to control robots (Optional)}
\subsubsection{Goal} Understand how events are used to control the robot.
\setcounter{subsubsection}{2}\subsubsection{Task} Create a piston and change its state twice over the course of two seconds.

\subsection{Self-reregistering events}
\subsubsection{Goal} Understand how single events can be sequenced with themselves to run an event a given number of times.
\setcounter{subsubsection}{2}\subsubsection{Task} Write an event which will execute four times, printing each time.

\subsection{[NullPointerException]} This section is empty; skip it for the time being.


\pagebreak\section{Listener Manager}\setcounter{subsection}{17}
\subsection{Registering events with \lstinline{ListenerManager}}
\subsubsection{Goal} Understand how \lstinline{ListenerManager} and how listener callbacks work.
\subsubsection{Details} \lstinline{ListenerManager} associates strings and integers with events. When an event is registered with the \lstinline{ListenerManager}, it must be given an associated \lstinline{String} or \lstinline{int}, known as the ``key, '' and frequently the ``listener.'' Note: Any \lstinline{String} keys will be converted to a \lstinline{String.hashCode()}, and be registered as an \lstinline{int}.

When the key is invoked, the \lstinline{ListenerManager} will go through the list and find all \lstinline{Event}s with matching keys, then execute them in order. For example, let's say I have an \lstinline{Event}:

\begin{lstlisting}
	Event e = new Event() {
		public void execute() {
			Global.motFL.setSpeed(0.5);
		}
	}
\end{lstlisting}

The \lstinline{Event} obviously will set the power of \lstinline{motFL} to 50\%. Now, what if I want to do this when I press the X button? (For the purposes of this example, we're assuming the controller's event is already running.)

\lstinline{ListenerManager.addListener(e, ''buttonXDown");} or:\newline\indent\lstinline{ListenerManager.addListener(e, ListenerConst.BTN_X_DOWN); //better for clarity}

The \lstinline{ListenerCosnt} class contains most of the available listener constants (keys). This is critically important for the listeners, as this greatly increases the clarity and consistency of what you're doing. For instance (and this has happened), one can make a typo in \lstinline{buttonXDown}, but one cannot easily make a typo in \lstinline{ListenerConst.BTN_X_DOWN}.

To invoke a listener/key, one simply needs to call \lstinline{ListenerManager.callListener()}; both a \lstinline{String} and an \lstinline{int} are acceptable arguments.
\subsubsection{Task} Create an \lstinline{Event}, and register it to trigger when the \lstinline{String "test"} is called.

\pagebreak\subsection{Running \lstinline{ListenerManager} callbacks}
\subsubsection{Goal} Call back events appropriately
\setcounter{subsubsection}{2}\subsubsection{Task} Create an event for \lstinline{"Hello "}, and event for \lstinline{"World"}, and register both of them under \lstinline{ListenerManager} for the key \lstinline{"helloworld"}. Call the \lstinline{"helloworld"} key after 1.5 seconds.
\subsubsection{Success} Program prints out \lstinline{"Hello World"} successfully.

\pagebreak\subsection{Setting up and running controllers}
\subsubsection{Goal} Understand how controllers interface with the program.
\subsubsection{Details} Controllers are all contained in \lstinline{frc3128.HardwareLink.Controller}. They are always \lstinline{Events}, and register themselves iterably when the constructors are run. 

As an example, we'll look at \lstinline{XControl}, which interfaces with an XBox 360 controller. Every iteration, \lstinline{XControl} checks to see if the controller's state has changed, and if so, what has. This is critically important for two reasons: first, it saves time. The program will only run what needs to be run when it needs to be run. Second, it's cleaner; the controller runs in the background, and buttons can be easily interlaced with the running program.

Controllers require a port number; this goes back to the driver station. Controllers should always be global resources.
\subsubsection{Task} Create an XBox controller (\lstinline{XControl}) on port 1. Make it such that, when button X is pressed, the program will print out "hello" for 1.5 seconds, then stop. Make it such that, when button Y is pressed, the program will print out "world" for 1.5 seconds, then stop.

\pagebreak\subsection{Creating an event for driving}
\subsubsection{Goal} Create a rudimentary driving \lstinline{Event}.
\subsubsection{Details} Drive events are not iterable events; instead, they are registered with \lstinline{ListenerManager} and are called when controller updates occur. 
\subsubsection{Task} Create a Drive event which runs on \lstinline{UPDATE\_DRIVE} and will set the power of a \lstinline{motLeft} motor to the value of the Y axis on controller 1. The drive event should also set the power of a \lstinline{motRight} motor to the value of the Y axis on controller 2.


\pagebreak\section{Event Sequencing}\setcounter{subsection}{21}

\subsection{Creating and using the \lstinline{EventSequencer}}
\subsubsection{Goal} Understand how \lstinline{EventSequencer}s are used, how they make your life easier, and how they're used for autonomous.
\subsubsection{Details} \lstinline{EventSequencer} is a class which runs events in a given sequence. This is incredibly useful for things like turning a piston on, then off after half a second.

The \lstinline{EventSequencer} is most useful during autonomous, however. Since \lstinline{SequenceEvent}s define their own exit conditions, they are indefinitely versatile for use in autonomous; simply define an event, define when you consider the event complete, then move on to the next one. The entire autonomous program can be written this way. 

The tools for sequencing events are in the \lstinline{frc3128.EventManager.EventSequencer} package. A \lstinline{SequenceEvent} is still an \lstinline{Event}. A \lstinline{SingleSequence} is still a \lstinline{SequenceEvent}. An \lstinline{EventSequencer} is also an \lstinline{Event}.

The \lstinline{EventSequencer} is an iterable event which is run by the \lstinline{EventManager}. \lstinline{SequenceEvent}s are always written to be single events, but have another abstract method: \lstinline{exitConditionMet()}. When \lstinline{exitConditionMet()} returns \lstinline{true}, the event is stopped, and the \lstinline{EventSequencer} moves on to the next event in the queue.

Each \lstinline{SequenceEvent} has several protected methods, one of which is \lstinline{getRunTimeMillis()}. This method is used to determine how long the event has been running, and is useful for \lstinline{SequenceEvent.exitConditionMet()} methods which return true when the a time limit expires.

A \lstinline{SingleSequence} event is a special case of the \lstinline{SequenceEvent} and is, for all intents and purposes, syntactic sugar. It provides an easy way to create an event which will run once and only once. Even though the \lstinline{EventSequencer} requires a \lstinline{SequenceEvent}, remember that a \lstinline{SingleSequence} is \textit{also} a \lstinline{SequenceEvent}; that's the way inheritance works.

A \lstinline{SingleSequence}'s \lstinline{exitConditionMet()} method reads:

\begin{lstlisting}
	/**
	 * Exits immediately; will always return true.
	 * 
	 * @return true
	 */
	public final boolean exitConditionMet() {return true;}
\end{lstlisting}

The \lstinline{EventSequencer} works off FIFO, so whatever you register with it first will run first.

The \lstinline{EventSequencer} will start when \lstinline{EventSequencer}'s \lstinline{startSequence()} method is invoked. To run it more than once, one must \lstinline{resetSequence()}. One can always \lstinline{stopSequence()}. 
\subsubsection{Task} Create an \lstinline{EventSequencer} and add a \lstinline{"Hello"} \lstinline{SingleSequence} to it, as well as a \lstinline{"World"} \lstinline{SingleSequence}. Trigger the \lstinline{EventSequencer}.

\pagebreak\subsection{Using alternative event sequencing}
\subsubsection{Goal} Use alternate exit conditions.
\subsubsection{Details} None.
\subsubsection{Task} Create a \lstinline{SequenceEvent} and have it print out until it exits in 1.5 seconds. Trigger two other events after this.

\section*{You win!}
\end{document}

%\subsection{Task 00}
%\subsubsection{Goal}
%\subsubsection{Details}
%\subsubsection{Task}
%\subsubsection{Success}